#include <iterator>
#include <unistd.h>
#include "MarkupSTL.h"
#include "global.h"
#include "cmd.h"
#include "Game.h"
#include "RedisClient.h"
#include "Logic.h"
#include "json.h"
#include "globalExtern.h"
#include "Host.h"
#include <string>
#include <algorithm>
#include "log.h"
#include "util.h"
#include "base64.h"
#include "Md5.h"
#include "bsl_string.h"
#include <sstream>
#include <map>
#include <time.h>
#include <cstdlib>
#include "public_define.h"
#include "cache.h"
#include "minutelisten.h"
#include "agencymgr.h"
#include "1650_agentbackend.pb.h"
#include "1800_agency.pb.h"
#include "2000_topic.pb.h"
#include "TopicHandler.h"
#include "LogHandler.h"
#include "currencymgr.h"



CGameServer::CGameServer()
{
}

CGameServer::~CGameServer()
{
}

int CGameServer::OnBYTimeOut(int Timerid)
{
	switch (Timerid)
	{
	case TimerID::TIMER_MINITE:
		MinuteListen::Instance()->OnTick();
		StartTimer(TimerID::TIMER_MINITE, 60, false);
		break;
	
	default:
		break;
	}
	return 0;
}

bool CGameServer::InitGame()
{
	log_info("game init");
	char conf_path[128] = "./config.xml";
	if (!ReadCommonConf(conf_path))
	{
		log_boot("InitGame ReadCommonConf failed. path:[%s]", conf_path);
		return false;
	}

	StartTimer(TimerID::TIMER_MINITE, 60, false);
	return true;
}

bool CGameServer::ReadCommonConf(const char* strxml)
{
	return true;
}


int CGameServer::ProcessPacket(SocketHandler * pHandler, NETInputPacket* inputPkg)
{
	do
	{
		int cmd = inputPkg->GetCmdType();
		log_debug("cmd=0x%x,  svid=%d, ", cmd, pHandler->getId());

		if (0 == TopicHandler::Instance()->ProcessPacket(m_pHost, pHandler, inputPkg))
		{
			break;
		}
		else if (0 == LogHandler::Instance()->ProcessPacket(m_pHost, pHandler, inputPkg))
		{
			break;
		}

		switch (cmd)
		{
			case agency_proto::AGENCY_CMD_GET_REQ:
				log_debug("ProcGet init");
				ProcGet(pHandler, inputPkg);
				break;
			case agentbackend::AGENT_BACKEND_MSG_ID_REFRESH_CONFIG:
				log_debug("ProcRefreshConfig init");
				ProcRefreshConfig(pHandler, inputPkg);
				break;
			default:
				log_error("cmd=0x%x,  svid=%d, err no proc", cmd, pHandler->getId());
				break;
		}
		return 1;
	}while(0);
	return -1;
}

void CGameServer::ProcGet(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
	agency_proto::GetReq req;
	agency_proto::GetResp resp;
	do
	{
		if (!inputPkg->parsePb(&req))
		{
			log_error("parse pb agency_proto::GetReq failed");
			resp.set_err_code(1);
			break;
		}
		log_debug("req:%s", req.ShortDebugString().c_str());
		resp.mutable_agency()->set_name(req.name());
		resp.mutable_agency()->set_id(req.id());
		resp.set_trans(req.trans());

		stAgency* agency = nullptr;
		if (req.name().empty())
		{
			agency = AgencyMgr::Instance()->Get(req.id());
		}
		else
		{
			agency = AgencyMgr::Instance()->Get(req.name());
		}
		if (agency == nullptr)
		{
			log_error("get agency failed,%s", req.ShortDebugString().c_str());
			resp.set_err_code(3);
			break;
		}
		agency->CopyTo(*resp.mutable_agency());

		stCurrency* currency = CurrencyMgr::Instance()->Get(agency->currency);
		if (currency == nullptr)
		{
			log_error("get currency failed,currency:%s, req:%s", agency->currency.c_str(), req.ShortDebugString().c_str());
			resp.set_err_code(4);
			break;
		}
		resp.mutable_agency()->set_currency_unit_multi(currency->unit_multi);
		resp.mutable_agency()->set_currency_label(currency->label);
		resp.set_err_code(0);
	} while (false);
	log_debug("resp:%s", resp.ShortDebugString().c_str());
	m_pHost->SendPb(pHandler, agency_proto::AGENCY_CMD_GET_RESP, &resp);
}

void CGameServer::ProcRefreshConfig(SocketHandler* pHandler, NETInputPacket* inputPkg)
{
    log_debug("enter");
    agentbackend::RefreshConfigNotify notify;
	do
	{
		bool bRet = inputPkg->parsePb(&notify);
		if (!bRet)
		{
			log_error("parse RefreshConfigNotify failed");
			break;
		}

        // 只要有通知,表明对应缓存有变化,则清空缓存,等待重新加载
        for (int i = 0; i < notify.config_size(); i++)
        {
            auto& item = notify.config(i);
			log_info("key:%s", item.configname().c_str());
			if (0 == item.configname().compare("agency"))
			{
				std::uint32_t agency_id = ::atoi(item.config().c_str());
				stAgency* st_agency = AgencyMgr::Instance()->RefreshGet(agency_id);
				if (st_agency == nullptr)
				{
					log_error("refresh agency:%d delete", agency_id);
					continue;
				}
						
				agency_proto::Agency agency;
				st_agency->CopyTo(agency);
				
				stCurrency* currency = CurrencyMgr::Instance()->Get(agency.currency());
				if (currency == nullptr)
				{
					log_error("get currency failed,currency:%s", agency.currency().c_str());
					continue;
				}
				agency.set_currency_unit_multi(currency->unit_multi);
				agency.set_currency_label(currency->label);
				
				OnAgencyUpdate(agency);
			}
        }
	}while(0);
}


void CGameServer::OnAgencyUpdate(const agency_proto::Agency& agency)
{
	topic_proto::Topic topic;
	topic.set_topic_event(topic_proto::TopicEvent::TOPIC_EVENT_AGENCY_UPDATE);
	topic.set_id(agency.id());
	topic.set_uuid(agency.name());
	agency.SerializeToString(topic.mutable_data());
	log_info("topic:%s", topic.ShortDebugString().c_str());
	
	TopicHandler::Instance()->Dispatch(m_pHost, topic);
	// m_pHost->SendtoSrv(topic_proto::TOPIC_CMD_PUBLISH_PUSH, SERVER_TYPE_TOPIC, &topic, CTools::Hash2Int(agency.name()));
}











